<script setup lang="ts">
import {onMounted,watch,ref} from 'vue'
import * as Cesium from "cesium";
import {MapMode2D, SceneMode,MaterialAppearance,GroundPrimitive} from "cesium";
import { getCookie } from '@/utils/httpParamsHandler';
import { getVectorParcelByQueryParams } from './api/mapApi.js'
import gisAppConfig from './config/GISAppConfig'
const emit = defineEmits([
  'onClick',
  'init',
  'getLandList'
])
const props = defineProps({
  domId:{
    type:String,
    default:'mobile-map-view'
  },
  location:{
    type:Object,
    default:{
      latitude:0,
      longitude:0
    }
  },
  loadingLand:{
    type:Boolean,
    default:true
  },
  queryString:{
    type:String,
    default:''
  }
})
//三维浏览器
let viewer:any = null
//地块图层
let parcelLayer:any = null
let parcelLayerText:any=null
//地块选中
let changEntityColor:any=null
const clickCount = ref(0)

watch(()=>props.location,()=>{
  viewer.camera.flyTo({
    destination: Cesium.Cartesian3.fromDegrees(props.location.longitude, props.location.latitude, 500),
    orientation: {
      heading: Cesium.Math.toRadians(0),
      pitch: Cesium.Math.toRadians(-90),
      roll: Cesium.Math.toRadians(0)
    },
    duration:1
  });
})
onMounted(() => {
  initMap()
})

const initDefaultAccessToken=()=>{
  //Cesium图标默认token
  Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI2NGM4MDcxOS05Zjk3LTQ2YmMtYjAxYi0zYTczNWFkYzFlN2EiLCJpZCI6NzY0NTcsImlhdCI6MTYzOTQ2ODI2NH0.Zsp28WnnCpj4wlAIQwIwcSob228zSaz510QE3zKQN58'
}

const modifyClarity=()=>{
  viewer.scene.fxaa = false
  viewer.scene.globe.maximumScreenSpaceError = 4/3
}

const initMap=()=>{
  initDefaultAccessToken()
  viewer = new Cesium.Viewer(props.domId,{
            sceneMode:SceneMode.SCENE3D,
            //mapProjection:new GeographicProjection(),4
            //globe:new Globe(mapProjection.ellipse),
            //orderIndependentTranslucency:true,
            //creditContainer:undefined,
            //creditViewport:undefined,
            //dataSources:new DataSourceCollection(),
            // terrainExaggeration:1,
            shadows:false,
            mapMode2D:MapMode2D.INFINITE_SCROLL,
            projectionPicker:false,
            requestRenderMode:false,
            maximumRenderTimeChange:0.0,
            animation:false,
            baseLayerPicker:false,
            fullscreenButton:false,
            vrButton:false,
            geocoder:false,
            homeButton:false,
            infoBox:false,
            sceneModePicker:false,
            selectionIndicator:false,
            timeline:false,
            navigationHelpButton:false,
            navigationInstructionsInitiallyVisible:false,
            scene3DOnly:false,
            shouldAnimate:false,
            //clockViewModel:new ClockViewModel(options.clock),
            //selectedImageryProviderViewModel:null,
            //imageryProviderViewModels:null,
            //selectedTerrainProviderViewModel:null,
            //terrainProviderViewModels:null,
            //imageryProvider:null,
            //terrainProvider:Cesium.createWorldTerrain(),
            //skyBox:undefined,
            //skyAtmosphere:false,
            //fullscreenElement:document.body,
            //useDefaultRenderLoop:true,
            //targetFrameRate:undefined,
            //showRenderLoopErrors:true,
            //useBrowserRecommendedResolution:false,
            //automaticallyTrackDataSourceClocks:true,
            //contextOptions:null,
        })

      viewer.cesiumWidget.creditContainer.style.display = "none"
      viewer.scene.globe.depthTestAgainstTerrain = true
      modifyClarity()
      //初始化定位
      viewer.camera.flyTo({
        destination: Cesium.Cartesian3.fromDegrees(Number(getCookie('longitude')||0)||106.584906,Number(getCookie('latitude')||0)|| 29.48, 10000),
        orientation: {
          heading: Cesium.Math.toRadians(0),
          pitch: Cesium.Math.toRadians(-90),
          roll: Cesium.Math.toRadians(0)
        },
        duration:1
      });
      initLayer()
  emit('init',viewer)
}

const initLayer=()=>{
  addLoadingImage()
  //加载地块图层(WMS图层)
  if(props.loadingLand){
    loadWMSParcelLayer()
  }
}

const addLoadingImage=async ()=> {
  
    // viewer.terrainProvider = await Cesium.createWorldTerrainAsync({
    //   requestVertexNormals: false,
    //   requestWaterMask: false
    // });

  //全球影像中文注记服务
    let imageryLayers = viewer.scene.imageryLayers;
    let tdtAnnoLayer = imageryLayers.addImageryProvider(new Cesium.WebMapTileServiceImageryProvider({
        url: "https://t0.tianditu.gov.cn/cva_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={TileMatrix}&TILEROW={TileRow}&TILECOL={TileCol}&tk=4cc66d27a3ef65764e7a58096e89aaf2",    
        layer: "tdtAnnoLayer",
        style: "default",
        format: "image/jpeg",
        tileMatrixSetID: "GoogleMapsCompatible" 
     }));
    tdtAnnoLayer.alpha = 0.5;
    tdtAnnoLayer.brightness = 2.0;

        //农场真实背景图层
        let geoserverWMSImageryUrl =`${gisAppConfig.GISServiceUrl}/geoserver/${gisAppConfig.ImageryNameSpace}/wms`
    let geoserverWMSImageryLayerName = `${gisAppConfig.ImageryNameSpace}:${gisAppConfig.ImageryLayerName}`
    let geoserverWebMapServiceImageryProvider = new Cesium.WebMapServiceImageryProvider(
      {
        url: geoserverWMSImageryUrl,
        layers: geoserverWMSImageryLayerName,
        parameters: {
          service: "wms",
          request: "GetMap",
          transparent: true,
          format: "image/png",
          srs: "EPSG:4326",
          version: "1.1.1",
          width: 256,
          height: 256
        },
        enablePickFeatures: true,
        tileWidth: 256,
        tileHeight: 256,
        minimumLevel: 0,
        maximumLevel: 18,
        srs: "EPSG:4326"
      });
    let imageryLayer = new Cesium.ImageryLayer(
      geoserverWebMapServiceImageryProvider,
      {
        alpha: 1.0,
        nightAlpha: 1.0,
        dayAlpha: 1.0,
        brightness: 1.0,
        contrast: 1.0,
        hue: 0.0,
        saturation: 1.0,
        gamma: 1.0,
        splitDirection: Cesium.SplitDirection.NONE,
        minificationFilter: Cesium.TextureMinificationFilter.LINEAR,
        magnificationFilter: Cesium.TextureMagnificationFilter.LINEAR,
        colorToAlphaThreshold: 0.004,
        minimumTerrainLevel: 0,
        show: true
      });
      imageryLayers.add(imageryLayer);
}

const loadWMSParcelLayer=()=>{
  //获取三维地图容器中的影像图层集合
  let imageryLayers = viewer.imageryLayers;
  //将geoserverWMSImageryLayer添加到图层集合中
  parcelLayer = initMapData({mounted:props.domId,viewer:viewer})
  imageryLayers.add(parcelLayer);
  //地块名称
   parcelLayerText = initMapData({mounted:props.domId,viewer:viewer,LandNameType:true})
  imageryLayers.add(parcelLayerText);
}
//查询地块
const queryLandList = (data)=>{
  clickCount.value=0
  let querystr=''
    Object.keys(data).forEach(key => {
    if(data[key]){
      if(key.indexOf('name')>=0){
        querystr +=` and ${key} like '${data[key]}%'`
      }else{
        querystr +=` and ${key}=${data[key]}`
      }
    }
    })
   if(parcelLayer){
      viewer.imageryLayers.remove(parcelLayer);
    }
    if(parcelLayerText){
      viewer.imageryLayers.remove(parcelLayerText);
    }
    //地块图形展示
    parcelLayer = initMapData({mounted:props.domId,viewer:viewer,queryString:querystr})
    viewer.imageryLayers.add(parcelLayer);
    //地块名称展示添加
    parcelLayerText = initMapData({mounted:props.domId,viewer:viewer,queryString:querystr,LandNameType:true})
    viewer.imageryLayers.add(parcelLayerText);
}
//累加查询地块
const accumulationQueryLandList = (querystr)=>{
    //地块图形展示
    parcelLayer = initMapData({mounted:props.domId,viewer:viewer,queryString:querystr})
    viewer.imageryLayers.add(parcelLayer);
    //地块名称展示添加
    parcelLayerText = initMapData({mounted:props.domId,viewer:viewer,queryString:querystr,LandNameType:true})
    viewer.imageryLayers.add(parcelLayerText);
}
//查询已经当前农场所有地块地块
const getFarmLandList = async (data:any)=>{
  let querystr=''
  Object.keys(data).forEach(key => {
  if(data[key]){
    if(key.indexOf('name')>=0){
      querystr +=` and ${key} like '${data[key]}%'`
    }else{
      querystr +=` and ${key}=${data[key]}`
    }
  }
  //CQL_FILTER:`villagename like '官进村%' or villagename like '护普村%'`
  });
  let geoserverWFSUrl = gisAppConfig.GISServiceUrl + "/geoserver/" + gisAppConfig.VectorNameSpace + "/wfs?";
  let layerName = gisAppConfig.VectorNameSpace + ":" + gisAppConfig.VectorParcelLayerName;
  let queryString ='' 
  if(querystr){
        queryString = `farmid=${getCookie('farmId')}${querystr}` 
      }else{
        queryString = `farmid=${getCookie('farmId')}` 
    }
    if(props.queryString){
              queryString = `${queryString}${props.queryString}`
      }
  let params = {
    service: 'WFS',
    version: '1.0.0',
    request: 'GetFeature',
    typeName: layerName,
    maxFeatures: 20000,
    outputFormat: "application/json",
    CQL_FILTER: queryString
  }
  let res = await getVectorParcelByQueryParams(geoserverWFSUrl, params)
  if (res?.status == 200) {
    emit('getLandList',res.data||[])
  }
}

//加载地图
const initMapData=(options:any)=>{
        let gfif = new Cesium.GetFeatureInfoFormat('json', 'application/json', (event)=>{
            if(event?.features.length>0){
              emit('onClick',event)
            } 
        })

        let serviceUrl = Cesium.defaultValue(options.serviceUrl,gisAppConfig.GISServiceUrl)
        let namespace = Cesium.defaultValue(options.namespace,gisAppConfig.VectorNameSpace)
        let layerName =options?.LandNameType?Cesium.defaultValue(options.layerName,gisAppConfig.ImageryParcelLabelLayerName):Cesium.defaultValue(options.layerName,gisAppConfig.VectorParcelLayerName)
        let geoserverWMSImageryUrl = `${serviceUrl}/geoserver/${namespace}/wms`
        let parceLayerName = namespace + ":" + layerName
        let queryString=''
          if(options?.queryString){
              queryString = `farmid=${getCookie('farmId')}${options.queryString}` 
            }else{
              queryString = `farmid=${getCookie('farmId')}` 
          }
          if(props.queryString){
              queryString = `${queryString}${props.queryString}`
          }
          console.log(queryString,'=============')

        let geoserverWebMapServiceImageryProvider = new Cesium.WebMapServiceImageryProvider(
          {
              url: geoserverWMSImageryUrl,
              layers:parceLayerName,
              parameters: {
                  service: "wms",
                  request: "GetMap",
                  transparent: true,
                  format: "image/png",
                  srs: "EPSG:4326",
                  version: "1.1.1",
                  width: 256,
                  height: 256,
                  /**
                   * sql查询条件,其中的属性值为:
                   * (1)CQL_FILTER:为模糊查询条件
                   * (2)OGC:为ogc标准的空间过滤
                   * (3)FeatureID:根据要素id进行查查询
                   */
                  //CQL_FILTER:`villagename like '官进村%' or villagename like '护普村%'`
                  CQL_FILTER:queryString
              },
              enablePickFeatures: true,
              getFeatureInfoFormats:options?.LandNameType?[]:(clickCount.value==0?[gfif]:[]),
              tileWidth: 256,
              tileHeight: 256,
              minimumLevel: 0,
              maximumLevel: 18,
              srs: "EPSG:4326"
          }
        );
        if(!options?.LandNameType){
          clickCount.value =1
        }
        let parcelLayer = new Cesium.ImageryLayer(geoserverWebMapServiceImageryProvider, {
            alpha: 1.0,
            nightAlpha: 1.0,
            dayAlpha: 1.0,
            brightness: 1.0,
            contrast: 1.0,
            hue: 0.0,
            saturation: 1.0,
            gamma: 1.0,
            splitDirection: Cesium.SplitDirection.NONE,
            minificationFilter: Cesium.TextureMinificationFilter.LINEAR,
            magnificationFilter: Cesium.TextureMagnificationFilter.LINEAR,
            colorToAlphaThreshold: 0.004,
            minimumTerrainLevel: 0,
            show: true
        });
        return parcelLayer
}

//地块选中高亮
const selectMapLands =(farmLandId:any,coordinates:any,color='rgb(0,255,217,0.4)')=>{
  if(!coordinates.length){return}
  if(changEntityColor){
      viewer.scene.primitives.remove(changEntityColor)
    }
  if(Cesium.defined(coordinates)){
      let positions = Cesium.Cartesian3.fromDegreesArray(coordinates)
      let polygonHierarchy = new Cesium.PolygonHierarchy(positions)
      let polygonGeometry = new Cesium.PolygonGeometry({
        polygonHierarchy:polygonHierarchy,
        height:0,
        extrudedHeight:0,
        vertexFormat:Cesium.VertexFormat.DEFAULT,
        stRotation:0.0,
        ellipsoid:Cesium.Ellipsoid.WGS84,
        granularity:Cesium.Math.RADIANS_PER_DEGREE,
        perPositionHeight:false,
        closeTop:true,
        closeBottom:true,
        arcType:Cesium.ArcType.GEODESIC,
      })

      let polygonGeometryInstance = new Cesium.GeometryInstance({
        geometry:polygonGeometry,
        modelMatrix:Cesium.Matrix4.IDENTITY,
        id:farmLandId,
        attributes:{
          color:Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.RED)
        }
      })

      let polygonAppearance = new Cesium.MaterialAppearance({
        flat:true,
        faceForward:false,
        translucent:true,
        closed:false,
        materialSupport:MaterialAppearance.MaterialSupport.TEXTURED,
        material:Cesium.Material.fromType('Color',{
          color:new Cesium.Color.fromCssColorString(color)
        })
      })

      let selectLdatas:any = new Cesium.GroundPrimitive({
        geometryInstances:polygonGeometryInstance,
        appearance:polygonAppearance,
        show:true,
        vertexCacheOptimize:false,
        interleave:false,
        compressVertices:true,
        releaseGeometryInstances:true,
        allowPicking:true,
        asynchronous:true,
        classificationType:Cesium.ClassificationType.BOTH,
        debugShowBoundingVolume:false,
        debugShowShadowVolume:false
      })
      changEntityColor= viewer.scene.primitives.add(selectLdatas)
  }
}
 const getHighLightFeature =(farmLandId:any)=>{
    let primitives = viewer.scene.primitives._primitives
    let highLightFeature = undefined
    if(Cesium.defined(primitives)){
      for(let i = 0; i < primitives.length;i++){
        //获取primitives对象
        let primitive = primitives[i]
        let isGroundPrimitive = primitive instanceof GroundPrimitive
        if(isGroundPrimitive){
          if(Cesium.defined(primitive)){
            let geometryInstances = primitive._classificationPrimitiveOptions.geometryInstances
            if(Cesium.defined(geometryInstances)){
              for(let i=0;i< geometryInstances.length;i++){
                //获取几何实例的几何
                let geometry = geometryInstances[i]
                //如果几何的id为"highLightPrimitive"
                if(geometry.id === farmLandId){
                  //该primitive是要查找的高亮要素，返回该primitive
                  highLightFeature = primitive
                  return highLightFeature
                }
              }
            }
            else{
              return undefined
            }
          }
        }
      }
    }
    else{
      return undefined
    }
 }
//移除单个选中地块
const removeLandColor =(farmLandId:any)=>{
  viewer.scene.primitives.remove(getHighLightFeature(farmLandId))
}
//地块选中高亮
const selectFarmLandChangeColor =(farmLandId:any,coordinates:any,color='#04ae70')=>{
      let positions = Cesium.Cartesian3.fromDegreesArray(coordinates)
      let polygonHierarchy = new Cesium.PolygonHierarchy(positions)
      let polygonGeometry = new Cesium.PolygonGeometry({
        polygonHierarchy:polygonHierarchy,
        height:0,
        extrudedHeight:0,
        vertexFormat:Cesium.VertexFormat.DEFAULT,
        stRotation:0.0,
        ellipsoid:Cesium.Ellipsoid.WGS84,
        granularity:Cesium.Math.RADIANS_PER_DEGREE,
        perPositionHeight:false,
        closeTop:true,
        closeBottom:true,
        arcType:Cesium.ArcType.GEODESIC,
      })
      let polygonGeometryInstance = new Cesium.GeometryInstance({
        geometry:polygonGeometry,
        modelMatrix:Cesium.Matrix4.IDENTITY,
        id:farmLandId,
        attributes:{
          color:Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.RED)
        }
      })

      let polygonAppearance = new Cesium.MaterialAppearance({
        flat:true,
        faceForward:false,
        translucent:true,
        closed:false,
        materialSupport:MaterialAppearance.MaterialSupport.TEXTURED,
        material:Cesium.Material.fromType('Color',{
          color:new Cesium.Color.fromCssColorString(color)
        })
      })

      let selectLdatas = new Cesium.GroundPrimitive({
        geometryInstances:polygonGeometryInstance,
        appearance:polygonAppearance,
        show:true,
        vertexCacheOptimize:true,
        interleave:false,
        compressVertices:true,
        releaseGeometryInstances:true,
        allowPicking:true,
        asynchronous:false,
        classificationType:Cesium.ClassificationType.BOTH,
        debugShowBoundingVolume:false,
        debugShowShadowVolume:false
      })
      viewer.scene.primitives.add(selectLdatas)
}

//移除所有选中地块
const removeFarmLandChangeColor =()=>{
   viewer.scene.primitives.removeAll()
}

//定位到多地块的中心位置
const setMapCenter =(coordinates:any)=>{
  if(!coordinates.length){return}
  let entities = coordinates.map((point:any)=>{ 
    return new Cesium.Entity({
      position: Cesium.Cartesian3.fromDegrees(point.lon, point.lat)
    })
  })
  // 计算包围这些点的球体
  let boundingSphere = new Cesium.BoundingSphere();
      Cesium.BoundingSphere.fromPoints(entities.map((entity:any)=> {
        return entity.position.getValue(Cesium.JulianDate.now());
      }), boundingSphere);
    // 将相机定位到球体中心
    viewer.scene.camera.flyToBoundingSphere(
      boundingSphere, 
      {
      offset: {
              heading: Cesium.Math.toRadians(0),
              pitch: Cesium.Math.toRadians(-90),
              range: Cesium.Math.toRadians(0)
      },
      duration:1
  })
}
defineExpose({
  selectMapLands,
  queryLandList,
  getFarmLandList,
  removeLandColor,
  selectFarmLandChangeColor,
  removeFarmLandChangeColor,
  setMapCenter,
  accumulationQueryLandList
})
</script>

<template>
  <div style="width: 100%;
    height: 100%;
    overflow: hidden;
    position: relative;">
    <div :id="domId" style="height: 100%;width: 100%;position: absolute; "></div>
  </div>
</template>


